package com.parking.gateway.file;

import com.parking.common.core.model.Result;
import com.parking.common.core.util.JwtUtil;
import com.parking.gateway.config.AuthorizationUrlConfig;
import com.parking.gateway.exception.AuthenException;
import com.parking.gateway.util.FilterUtil;
import com.parking.gateway.util.RedisUtil;
import com.parking.gateway.util.StringMatchUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
@Order(2)
public class CertifiedLoginAuthenFilter implements GlobalFilter {

        @Autowired
        private AuthorizationUrlConfig urlConfig;

        @Autowired
        private RedisUtil redisUtil;

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                String path = exchange.getRequest().getPath().toString();
                if (path.endsWith(".certified")) {
                        System.out.println("111111111111111111111111111111");
                        if (StringMatchUtil.match(path, urlConfig.getCertifiedUrls())) return chain.filter(exchange);
                        List<String> auths = exchange.getRequest().getHeaders().get("authorization");
                        if (auths == null || auths.isEmpty()) {
                                Result result = Result.getResult().setMessage("后台未登录").setCode(403);
                                return FilterUtil.negative(exchange, result);
                        } else {
                                try {
                                        JwtUtil.parseCertifiedToken(auths.get(0));
                                        return chain.filter(exchange);
                                } catch (Exception e) {
                                        String refreshToken = redisUtil.get(auths.get(0));
                                        try {
                                                Claims claims = JwtUtil.parseCertifiedToken(refreshToken);
                                                Integer certifiedAccountId = (Integer) claims.get("certifiedAccountId");
                                                String newAccessToken = JwtUtil.createCentifiedToken(30,"certifiedAccountId",certifiedAccountId);
                                                String newRefreshToken = JwtUtil.createCentifiedToken(3*24*60,"certifiedAccountId",certifiedAccountId);
                                                redisUtil.set(newAccessToken,newRefreshToken);
                                                redisUtil.del(auths.get(0));
                                                ServerHttpRequest request = exchange.getRequest().mutate().headers(httpHeaders -> {
                                                        httpHeaders.remove("authorization");
                                                        httpHeaders.add("authorization", newAccessToken);
                                                }).build();
                                                exchange.getResponse().getHeaders().add("authorization",newAccessToken);
                                                exchange.getResponse().getHeaders().add("Access-Control-Expose-Headers","authorization");
                                                return chain.filter(exchange.mutate().request(request).build());
                                        } catch (Exception ex) {
                                                Result result = Result.getResult().setMessage("后台未登录").setCode(403);
                                                System.out.println("CertifiedLoginAuthenFilter异常+11111111111111111111111");
                                                return FilterUtil.negative(exchange,result);
                                        }
                                }
                        }
                }
                return chain.filter(exchange);
        }
}
